package com.tongji.diy.model
{
	import com.tongji.diy.event.AddHoleEvent;
	import com.tongji.diy.event.SetRoomPositionEvent;
	import com.tongji.diy.event.SetRoomRotationEvent;
	import com.tongji.diy.event.ShowNewShapeEvent;
	import com.tongji.diy.event.UpdateRoomBorderEvent;
	import com.tongji.diy.event.UpdateRoomFloorEvent;
	import com.tongji.diy.event.UpdateRoomVertexEvent;
	import com.tongji.diy.event.UploadRoomPositionEvent;
	import com.tongji.diy.utils.PolygonMath;
	import com.tongji.diy.utils.RoomParameters;
	import com.tongji.diy.view.component3D.BaseRoomBorder;
	import com.tongji.diy.view.component3D.RoomBorder;
	import com.tongji.diy.view.component3D.RoomBorderArc;
	import com.tongji.diy.view.component3D.RoomFloor;
	import com.tongji.diy.view.component3D.RoomVertex;
	import com.tongji.diy.view.component3D.ShapeToAdd;
	import com.tongji.diy.view.component3D.ShapeToAddArc;
	import com.tongji.diy.view.component3D.ShapeToAddLWall;
	import com.tongji.diy.view.component3D.ShapeToAddRect;
	
	import de.polygonal.ds.DLinkedList;
	import de.polygonal.ds.DListNode;
	
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	
	import mx.containers.Panel;
	import mx.controls.List;
	import mx.core.INavigatorContent;
	
	import org.robotlegs.mvcs.Actor;
	
	/**
	 * 
	 * @author xxj
	 * 
	 */
	
	[Bindable]
	public class RoomDataModel extends Actor
	{
		public var roomIndex:uint = 0;
		private var _rooms:Vector.<RoomDataVO> = new Vector.<RoomDataVO>;
		private var currentRoom:RoomDataVO;
		private var rotateRoomIndex:int = -1;
		
		public function addRoom(roomData:RoomDataVO):void
		{
			_rooms.push(roomData);
			roomIndex++;
		}
		
		public function uploadRoomPosition(roomIndex:uint,position:Vector3D,register:Boolean):void
		{
			if (roomIndex<_rooms.length)
			{
				currentRoom = _rooms[roomIndex];
				currentRoom.x = position.x;
				currentRoom.y = position.z;
				
				
				currentRoom.updateBoundBox();
				//吸附
				atract()
				
				if (register)
					/*{
					roomOverlapJudge();
					}*/
					currentRoom.register();
			}
		}
		
		
		public function uploadRoomRotation(roomIndex:uint,rotation:Vector3D,register:Boolean):void
		{
			currentRoom = _rooms[roomIndex];
			if (rotation.x == 0)
				currentRoom.rotation = rotation.y;
			else
				currentRoom.rotation = 180 - rotation.y;
			
			if (register)
				currentRoom.register()
		}
		
		public function uploadVertex(roomVertex:RoomVertex,nodePosition:Point):void
		{
			currentRoom = roomVertex.node.data.parentRoom;
			currentRoom.updateBoundBox();
			currentRoom.updateRoomCenter();
			
			roomVertex.node.data.setPosition(nodePosition);
			// 存所有需要更新的边
			var updateBorderArray:Vector.<BaseRoomBorder> = new Vector.<BaseRoomBorder>();
			var node:DListNode = roomVertex.node.prev;
			if(node.data is RoomControlPointArc)
			{
				node = node.prev;
			}
			updateBorderArray.push(node.data.nextBorder);
			updateBorderArray.push(node.data.prevBorder);
			
			node = roomVertex.node.next;
			if(node.data is RoomControlPointArc)
			{
				node = node.next;
			}
			updateBorderArray.push(node.data.prevBorder);
			updateBorderArray.push(node.data.nextBorder);
			
			dispatch(new UpdateRoomBorderEvent(UpdateRoomBorderEvent.UPDATE_ROOM_BORDER,updateBorderArray));
			//更新的地板
			var updateFloor:RoomFloor = roomVertex.node.data.floor;
			dispatch(new UpdateRoomFloorEvent(UpdateRoomFloorEvent.UPDATE_ROOM_FlOOR,updateFloor));
			//更新顶点
			var updateVertexArray:Vector.<RoomVertex> = new Vector.<RoomVertex>();
			updateVertexArray.push(roomVertex);
			dispatch(new UpdateRoomVertexEvent(UpdateRoomVertexEvent.UPDATE_ROOM_VERTEX,updateVertexArray));
			/*frank 测试用*/
			var i:uint = roomVertex.node.data.parentRoom.roomIndex
			//trace(i,edgeIntersectAfterDragVertexInner(i),edgeIntersectAfterDragVertexOuter(i),clockwise(i));
		}
		
		public function uploadBorder(roomBorder:RoomBorder,startPosition:Point,endPosition:Point):void
		{
			currentRoom = roomBorder.start.data.parentRoom;
			currentRoom.updateBoundBox();
			currentRoom.updateRoomCenter();
			
			roomBorder.start.data.setPosition(startPosition);
			roomBorder.end.data.setPosition(endPosition);
			// 存所有需要更新的边
			var updateBorderArray:Vector.<BaseRoomBorder> = new Vector.<BaseRoomBorder>();
			//排除弧形墙控制点
			var node:DListNode = roomBorder.start.prev;
			if(node.data is RoomControlPointArc)
				node = node.prev;
			updateBorderArray.push(node.data.prevBorder);
			updateBorderArray.push(node.data.nextBorder);
			updateBorderArray.push(roomBorder.start.data.nextBorder);
			node = roomBorder.end.next;
			if(node.data is RoomControlPointArc)
				node = node.next;
			updateBorderArray.push(node.data.prevBorder);
			updateBorderArray.push(node.data.nextBorder);
			dispatch(new UpdateRoomBorderEvent(UpdateRoomBorderEvent.UPDATE_ROOM_BORDER,updateBorderArray));
			// 存所有需要更新的点
			var updateVertexArray:Vector.<RoomVertex> = new Vector.<RoomVertex>();
			updateVertexArray.push(roomBorder.start.data.vertex);
			updateVertexArray.push(roomBorder.end.data.vertex);
			dispatch(new UpdateRoomVertexEvent(UpdateRoomVertexEvent.UPDATE_ROOM_VERTEX,updateVertexArray));
			//更新的地板
			var updateFloor:RoomFloor = roomBorder.start.data.floor;
			dispatch(new UpdateRoomFloorEvent(UpdateRoomFloorEvent.UPDATE_ROOM_FlOOR,updateFloor));
		}
		
		public function addShape(roomBorder:RoomBorder, shapeToAdd:ShapeToAdd, room:RoomDataVO):void
		{
			var shapeType:uint = 0;
			
			/*
			计算shapeToAdd的顶点数据
			*/
			
			var roomShapePoints:Vector.<Point> = new Vector.<Point>;
			var normal:Point = roomBorder.getNormal();
			var deltaAngle:Number;
			if(normal.x>0)
			{
				deltaAngle = Math.atan(normal.y/normal.x) - Math.PI/2;
			}
			else if(normal.x<0)
			{
				deltaAngle = Math.atan(normal.y/normal.x) + Math.PI/2;
			}
			else
			{
				if(normal.y>0)
					deltaAngle = 0;
				else
					deltaAngle = Math.PI;
			}
			
			for(var j:uint=0;j<shapeToAdd.roomShapePoints.length;j++)
			{
				var point:Point = new Point(shapeToAdd.roomShapePoints[j].x, shapeToAdd.roomShapePoints[j].y);
				var angle:Number;
				if(point.x>0)
				{
					angle = Math.atan(point.y/point.x);
				}
				else if(point.x<0)
				{
					angle = Math.atan(point.y/point.x) + Math.PI;
				}
				else
				{
					angle = Math.PI/2;
				}
				var point2:Point = new Point(shapeToAdd.x+point.length*Math.cos(angle+deltaAngle), shapeToAdd.z+point.length*Math.sin(angle+deltaAngle));
				point2 = room.globalToLocal(point2);
				roomShapePoints.push(point2);
			}
			
			/*
			修改room顶点数据
			*/
			
			//
			var newPointArray:Vector.<DListNode>;
			var preNode:DListNode;
			var updateFloor:RoomFloor;
			
			if(shapeToAdd is ShapeToAddArc)
			{
				newPointArray = new Vector.<DListNode>;
				
				var roomControlPointArc:RoomControlPoint = new RoomControlPoint(roomShapePoints[0],room);
				var nodeArc:DListNode = new DListNode(roomControlPointArc);
				nodeArc.prev = roomBorder.start;
				roomBorder.start.next = nodeArc;
				newPointArray.push(nodeArc);
				preNode = nodeArc;
				
				var shapeToAddArc:ShapeToAddArc = shapeToAdd as ShapeToAddArc;
				for(j=0;j<shapeToAddArc.points.length;j++)
				{
					point = new Point(shapeToAddArc.points[j].x, shapeToAddArc.points[j].y);
					if(point.x>0)
					{
						angle = Math.atan(point.y/point.x);
					}
					else if(point.x<0)
					{
						angle = Math.atan(point.y/point.x) + Math.PI;
					}
					else
					{
						angle = Math.PI/2;
					}
					point2 = new Point(shapeToAddArc.x+point.length*Math.cos(angle+deltaAngle), shapeToAddArc.z+point.length*Math.sin(angle+deltaAngle));
					point2 = room.globalToLocal(point2);
					shapeToAddArc.points[j] = point2;
				}
				roomControlPointArc = new RoomControlPointArc(roomShapePoints[1],room,shapeToAddArc.points);
				nodeArc = new DListNode(roomControlPointArc);
				preNode.next = nodeArc;
				nodeArc.prev = preNode;
				newPointArray.push(nodeArc);
				preNode = nodeArc;
				
				roomControlPointArc = new RoomControlPoint(roomShapePoints[2],room);
				nodeArc = new DListNode(roomControlPointArc);
				preNode.next = nodeArc;
				nodeArc.prev = preNode;
				nodeArc.next = roomBorder.end;
				roomBorder.end.prev = nodeArc;
				newPointArray.push(nodeArc);
				
				dispatch(new ShowNewShapeEvent(ShowNewShapeEvent.SHOW_NEW_SHAPE_ARC,newPointArray,roomBorder,shapeType));
				
				updateFloor = room.roomPointList.head.data.floor;
				dispatch(new UpdateRoomFloorEvent(UpdateRoomFloorEvent.UPDATE_ROOM_FlOOR,updateFloor));
				
				return;
			}
			else
			{
				//第一个点
				var roomControlPoint:RoomControlPoint = new RoomControlPoint(roomShapePoints[0],room);
				var node:DListNode = new DListNode(roomControlPoint);
				node.prev = roomBorder.start;
				roomBorder.start.next = node;
				newPointArray = new Vector.<DListNode>;
				newPointArray.push(node);
				preNode = node;
				
				//除了第一和最后，中间的点
				for(var i:uint=1; i<roomShapePoints.length-1; i++)
				{
					roomControlPoint = new RoomControlPoint(roomShapePoints[i],room);
					node = new DListNode(roomControlPoint);
					node.prev = preNode;
					preNode.next = node;
					newPointArray.push(node);
					preNode = node;
				}
				
				/*
				 * 矩形墙*/
				
				if(shapeToAdd is ShapeToAddRect)
				{
					shapeType = 0;
					
					//最后的点
					roomControlPoint = new RoomControlPoint(roomShapePoints[roomShapePoints.length-1],room);
					node = new DListNode(roomControlPoint);
					node.prev = preNode;
					preNode.next = node;
					node.next = roomBorder.end;
					roomBorder.end.prev = node;
					newPointArray.push(node);
				}
				
				/*
				 * L型墙*/
	
				if(shapeToAdd is ShapeToAddLWall)
				{
					shapeType = 1;
					roomBorder.end.data.nextBorder.end.prev = newPointArray[newPointArray.length-1];
					newPointArray[newPointArray.length-1].next = roomBorder.end.data.nextBorder.end;
				}
			}
			
			/*
			发送数据给前台更新
			*/
			
			dispatch(new ShowNewShapeEvent(ShowNewShapeEvent.SHOW_NEW_SHAPE,newPointArray,roomBorder,shapeType));
			
			updateFloor = room.roomPointList.head.data.floor;
			dispatch(new UpdateRoomFloorEvent(UpdateRoomFloorEvent.UPDATE_ROOM_FlOOR,updateFloor));
		}
		
		//吸附
		private function atract():void
		{
			var roomIndex:uint = currentRoom.roomIndex;
			var roomMax:Point = currentRoom.roomMax;
			var roomMin:Point = currentRoom.roomMin;
			var finalOffset:Point = new Point();
			
			//made by frank
			var collisionRoomIndex:int = -1;
			var moveRoomPointList:Vector.<DListNode> = new Vector.<DListNode>;//碰撞点
			var collisionRoomPointAList:Vector.<DListNode> = new Vector.<DListNode>;//碰撞点所撞击的边的顶点
			var collisionRoomPointBList:Vector.<DListNode> = new Vector.<DListNode>;
			var collisionRoomPointA:DListNode;//碰撞点所撞击的边的顶点
			var collisionRoomPointB:DListNode;
			var offsetP:Vector3D;
			
			var sign:int = -1;//标示符，标志是点撞边，还是边撞点1为点撞边2为边撞点:Vector.<DListNode> = new Vector.<DListNode>
			var overlap:Boolean = false;//是否与别的房间发生重叠
			
			for (var i:uint = 0; i < _rooms.length; i++)
			{
				if (i != roomIndex &&
					_rooms[i].roomMax.x + RoomParameters.wallWidth > roomMin.x &&
					_rooms[i].roomMin.x - RoomParameters.wallWidth < roomMax.x &&
					_rooms[i].roomMax.y + RoomParameters.wallWidth > roomMin.y &&
					_rooms[i].roomMin.y - RoomParameters.wallWidth < roomMax.y)
				{
					var currentNode:DListNode;
					var currentNode2:DListNode;
					var offsetPoint:Vector3D;
					currentNode = currentRoom.roomPointList.head;
					
					while(1)
					{
						currentNode2 = _rooms[i].roomPointList.head;
						while(1)
						{
							offsetPoint = testOffset(new Point(currentNode2.data.globalX,currentNode2.data.globalY ), new Point(currentNode2.next.data.globalX,currentNode2.next.data.globalY ), new Point(currentNode.data.globalX,currentNode.data.globalY));
							if (offsetPoint.length < RoomParameters.wallWidth)
							{								
								if(offsetPoint.z == 1)
								{
									offsetP = offsetPoint;
								}
								finalOffset.x = offsetPoint.x;
								finalOffset.y = offsetPoint.y;
								
								//made by frank
								sign = 1;
								collisionRoomIndex = i;
								moveRoomPointList.push(currentNode);
								collisionRoomPointAList.push(currentNode2);
								collisionRoomPointBList.push(currentNode2.next);
							}
							currentNode2 = currentNode2.next;
							if (currentNode2 == _rooms[i].roomPointList.head)
								break;
						}
						currentNode = currentNode.next;
						if (currentNode == currentRoom.roomPointList.head)
							break;
					}
					
					currentNode = currentRoom.roomPointList.head;
					while(1)
					{
						currentNode2 = _rooms[i].roomPointList.head;
						while(1)
						{
							offsetPoint = testOffset(new Point(currentNode.data.globalX,currentNode.data.globalY ), new Point(currentNode.next.data.globalX,currentNode.next.data.globalY ), new Point(currentNode2.data.globalX,currentNode2.data.globalY))
							if (offsetPoint.length < RoomParameters.wallWidth)
							{
								if(offsetPoint.z == 1)
								{
									offsetP = new Vector3D(-offsetPoint.x,-offsetPoint.y);
								}
								finalOffset.x = -offsetPoint.x;
								finalOffset.y = -offsetPoint.y;	
								//made by frank
								sign = 2;
								collisionRoomIndex = i;
								moveRoomPointList.push(currentNode2);
								collisionRoomPointAList.push(currentNode);
								collisionRoomPointBList.push(currentNode.next);
							}
							currentNode2 = currentNode2.next;
							if (currentNode2 == _rooms[i].roomPointList.head)
								break
						}
						currentNode = currentNode.next;
						if (currentNode == currentRoom.roomPointList.head)
							break;
					}
					if(offsetPoint.z != 1 && offsetP != null)
					{
						finalOffset.x = offsetP.x;
						finalOffset.y = offsetP.y;
					}
					
					var H1:DListNode = currentRoom.roomPointList.head;
					var H2:DListNode = _rooms[i].roomPointList.head;
					while(1)
					{
						while(1)
						{
							var EAPA:Point = new Point(H1.data.globalX + finalOffset.x, H1.data.globalY + finalOffset.y);
							var EAPB:Point = new Point(H1.next.data.globalX + finalOffset.x, H1.next.data.globalY + finalOffset.y);
							var EBPA:Point = new Point(H2.data.globalX , H2.data.globalY);
							var EBPB:Point = new Point(H2.next.data.globalX, H2.next.data.globalY);
							var MP:Point = new Point((H1.data.globalX + H1.next.data.globalX)/2 + finalOffset.x,(H1.data.globalY + H1.next.data.globalY)/2 + finalOffset.y)
							if(!overlap && (PolygonMath.pointIsInPoly(H2, EAPA) || PolygonMath.edgeIntersect(EAPA,EAPB,EBPA,EBPB,true) || PolygonMath.pointIsInPoly(H2, MP)))
							{
								overlap = true;
								break;
							}
							H2 = H2.next;
							if(H2 == _rooms[i].roomPointList.head)
								break;
						}
						H1 = H1.next;
						if(H1 == currentRoom.roomPointList.head)
							break;
					}
					
				}
			}
			
			//made by frank
			//找出应该旋转的点以及应该旋转的对应边
			var moveRoomPoint:DListNode;
			var tempAngle:Number = Infinity;
			for(var k:int = 0; k < moveRoomPointList.length; k++)
			{
				var angle:Number = PolygonMath.rotationAngle(moveRoomPointList[k],collisionRoomPointAList[k],collisionRoomPointBList[k])
				if(tempAngle > Math.abs(angle))
				{
					tempAngle = Math.abs(angle);
					collisionRoomPointA = collisionRoomPointAList[k];
					collisionRoomPointB = collisionRoomPointBList[k];
					moveRoomPoint = moveRoomPointList[k];
				}
			}
			//对最终旋转位置以及旋转角度的计算
			var finalPosition:Point = new Point(currentRoom.x,currentRoom.y);
			var collisionVector:Vector.<Number>;
			var finalRotation:Number = currentRoom.rotation;
			if(!overlap && collisionRoomIndex != -1)
			{
				finalPosition = finalOffset.add(new Point(currentRoom.x,currentRoom.y));
				collisionVector = collisionAndRotation(currentRoom,_rooms[collisionRoomIndex],moveRoomPoint,collisionRoomPointA,collisionRoomPointB, finalOffset, sign);
				if(collisionVector[0] != finalRotation)
				{
					finalPosition = new Point(collisionVector[1], collisionVector[2]);
					finalRotation = collisionVector[0];
				}
			}
			
			dispatch(new SetRoomPositionEvent(SetRoomPositionEvent.SET_CURRENT_ROOM_POSITION,finalPosition));
			dispatch(new SetRoomRotationEvent(SetRoomRotationEvent.SET_CURRENT_ROOM_ROTATION,finalRotation));
		}
		
		public function collisionAndRotation(moveRoom:RoomDataVO, collisionRoom:RoomDataVO,moveRoomCollisionPoint:DListNode, collisionRoomEdgePointA:DListNode, collisionRoomEdgePointB:DListNode, finaloffset:Point, sign:int):Vector.<Number>
		{			
			var rotationMatrix1:Matrix = new Matrix(Math.cos(-moveRoom.rotation*Math.PI/180),Math.sin(-moveRoom.rotation*Math.PI/180),-Math.sin(-moveRoom.rotation*Math.PI/180),Math.cos(-moveRoom.rotation*Math.PI/180));	
			var rotationMatrix2:Matrix;
			var rotationPoint1:Point;
			var rotationPoint2:Point;
			var angle:Number
			
			if(sign == 1)//点撞边的情况
			{
				angle = PolygonMath.rotationAngle(moveRoomCollisionPoint, collisionRoomEdgePointA, collisionRoomEdgePointB);
				rotationPoint1 = rotationMatrix1.transformPoint(new Point(moveRoomCollisionPoint.data.x, moveRoomCollisionPoint.data.y));
				rotationMatrix2 = new Matrix(Math.cos(angle),Math.sin(angle),-Math.sin(angle),Math.cos(angle));
				rotationPoint2 = rotationMatrix2.transformPoint(new Point(rotationPoint1.x, rotationPoint1.y));
			}
			else//边撞点的情况
			{
				angle = - PolygonMath.rotationAngle(moveRoomCollisionPoint, collisionRoomEdgePointA, collisionRoomEdgePointB);
				rotationMatrix2 = new Matrix(Math.cos(angle),Math.sin(angle),-Math.sin(angle),Math.cos(angle));
				var collisionRotationPoint:Point = PolygonMath.pedal(new Point(collisionRoomEdgePointA.data.globalX, collisionRoomEdgePointA.data.globalY), new Point(collisionRoomEdgePointB.data.globalX, collisionRoomEdgePointB.data.globalY), new Point(moveRoomCollisionPoint.data.globalX,moveRoomCollisionPoint.data.globalY))
				rotationPoint1 = collisionRotationPoint;
				
				var moveMatrixP:Matrix = new Matrix(1,0,0,1,-moveRoom.x, -moveRoom.y);
				var moveMatrixN:Matrix = new Matrix(1,0,0,1,moveRoom.x, moveRoom.y);
				moveMatrixP.concat(rotationMatrix2);
				moveMatrixP.concat(moveMatrixN);
				rotationPoint2 = moveMatrixP.transformPoint(new Point(rotationPoint1.x, rotationPoint1.y));
			}
			
			var offset:Point = new Point(rotationPoint2.x - rotationPoint1.x, rotationPoint2.y - rotationPoint1.y);
			
			var finalPosition:Point = new Point(moveRoom.x - offset.x,moveRoom.y - offset.y);
			
			finalPosition = finalPosition.add(finaloffset);
			
			//以下内容是关于房间重叠的处理
			var collision:Boolean = false;
			if(sign == 1)
			{
				var moveMatrix1:Matrix = new Matrix(1,0,0,1,-moveRoomCollisionPoint.data.globalX,-moveRoomCollisionPoint.data.globalY);
				var moveMatrix2:Matrix = new Matrix(1,0,0,1,+moveRoomCollisionPoint.data.globalX,+moveRoomCollisionPoint.data.globalY);
			}
			else
			{
				moveMatrix1 = new Matrix(1,0,0,1,-collisionRotationPoint.x,-collisionRotationPoint.y);
				moveMatrix2 = new Matrix(1,0,0,1,+collisionRotationPoint.x,+collisionRotationPoint.y);
			}
			moveMatrix1.concat(rotationMatrix2);
			moveMatrix1.concat(moveMatrix2);
			var judgmentMatrix:Matrix = moveMatrix1;
			if(sign !=1)
			{
				var temp:DListNode = moveRoomCollisionPoint;
				moveRoomCollisionPoint = collisionRoomEdgePointA;
				collisionRoomEdgePointA = temp;
				collisionRoomEdgePointB = collisionRoomEdgePointA.next;
			}
			var tempHead:DListNode = moveRoomCollisionPoint;
			var tempVectorPoints:Vector.<Point> = new Vector.<Point>;
			var tempRoomMin:Point = new Point(Infinity,Infinity);
			var tempRoomMax:Point = new Point(-Infinity,-Infinity);
			
			while(1)
			{
				var tempPoint:Point = judgmentMatrix.transformPoint(new Point(moveRoomCollisionPoint.data.globalX, moveRoomCollisionPoint.data.globalY));
				tempPoint = tempPoint.add(finaloffset);
				tempVectorPoints.push(tempPoint);
				if(tempRoomMin.x > tempPoint.x)
					tempRoomMin.x = tempPoint.x;
				if(tempRoomMin.y > tempPoint.y)
					tempRoomMin.y = tempPoint.y;
				if(tempRoomMax.x < tempPoint.x)
					tempRoomMax.x = tempPoint.x;
				if(tempRoomMax.y < tempPoint.y)
					tempRoomMax.y = tempPoint.y;
				
				moveRoomCollisionPoint = moveRoomCollisionPoint.next;
				if(moveRoomCollisionPoint == tempHead)
					break;
			}
			
			for(var i:int = 0; i < _rooms.length; i++)
			{
				if (_rooms[i] != moveRoom &&
					_rooms[i].roomMax.x + RoomParameters.wallWidth > tempRoomMin.x &&
					_rooms[i].roomMin.x - RoomParameters.wallWidth < tempRoomMax.x &&
					_rooms[i].roomMax.y + RoomParameters.wallWidth > tempRoomMin.y &&
					_rooms[i].roomMin.y - RoomParameters.wallWidth < tempRoomMax.y)
				{
					var node:DListNode = _rooms[i].roomPointList.head;
					while(!collision)
					{
						for(var j:int = 0; j < tempVectorPoints.length; j++)
						{
							var PA:Point = new Point(node.data.globalX,node.data.globalY);
							var PB:Point = new Point(node.next.data.globalX,node.next.data.globalY);
							if(PolygonMath.edgeIntersect(tempVectorPoints[j], tempVectorPoints[(j+1)%tempVectorPoints.length],PA,PB,true))
							{
								collision = true;
								break;
							}
						}
						node = node.next;
						if(node == _rooms[i].roomPointList.head)
							break;
					}
				}
			}

			var returnVector:Vector.<Number> = new Vector.<Number>;
			if(!collision)
			{
				
				returnVector.push(-angle*180/Math.PI + moveRoom.rotation, finalPosition.x, finalPosition.y);
				return returnVector;
			}
			else
			{
				returnVector.push(moveRoom.rotation, moveRoom.x + finaloffset.x,moveRoom.y + finaloffset.y);
				return returnVector;
			}
			/*if(!collision)
			{
				dispatch(new SetRoomRotationEvent(SetRoomRotationEvent.SET_CURRENT_ROOM_ROTATION,-angle*180/Math.PI + moveRoom.rotation,true));
				dispatch(new SetRoomPositionEvent(SetRoomPositionEvent.SET_CURRENT_ROOM_POSITION,finalPosition));
			}
			else
			{
				dispatch(new SetRoomRotationEvent(SetRoomRotationEvent.SET_CURRENT_ROOM_ROTATION,moveRoom.rotation));
				dispatch(new SetRoomPositionEvent(SetRoomPositionEvent.SET_CURRENT_ROOM_POSITION,(new Point(moveRoom.x,moveRoom.y).add(finaloffset))));
			}*/
		}
		
		//判断testPoint到point1和point2间线段最短距离，返回值为testpoint指向线段最近点的向量。
		private function testOffset(point1:Point, point2:Point, testPoint:Point):Vector3D
		{
			var dis12:Point = point2.subtract(point1);
			var dis1t:Point = testPoint.subtract(point1);
			var f:Number = dis12.x * dis1t.x + dis12.y * dis1t.y;
			var vector:Vector3D;
			if (f<0)
			{
				vector = new Vector3D(point1.x-testPoint.x,point1.y-testPoint.y,1);
			}
			else if (f>dis12.length*dis12.length)
			{
				vector = new Vector3D(point2.x-testPoint.x,point2.y-testPoint.y,1);
			}
			else
			{
				var dis1p:Point = new Point(dis12.x * f / dis12.length / dis12.length, dis12.y * f/dis12.length/dis12.length);
				vector = new Vector3D(point1.x+dis1p.x-testPoint.x,point1.y+dis1p.y-testPoint.y,-1)
			}
			return vector
		}
		
		//求vec1和vec2夹角的余弦值
		private function getCos( vec1:Point, vec2:Point ):Number
		{
			if(vec1.length == 0 || vec2.length == 0)
				return 0;
			return ( ( vec1.x*vec2.x + vec1.y*vec2.y ) / (vec1.length*vec2.length) );
		}
		
		//开墙洞  xu
		public function addHole(position:Vector3D):void
		{
			var clickPosition:Point = new Point(position.x,position.z);
			var finalPosition:Point;
			for (var i:uint = 0; i < _rooms.length; i++)
			{
				var currentNode:DListNode = _rooms[i].roomPointList.head;
				do
				{
					var offsetPoint:Vector3D = testOffset(new Point(currentNode.data.globalX,currentNode.data.globalY ), new Point(currentNode.next.data.globalX,currentNode.next.data.globalY ), clickPosition)
					if (offsetPoint.length < RoomParameters.wallWidth+1&&offsetPoint.z == -1)
					{
						finalPosition = new Point(clickPosition.x+offsetPoint.x,clickPosition.y+offsetPoint.y)
						finalPosition = _rooms[i].globalToLocal(finalPosition);
						dispatch(new AddHoleEvent(AddHoleEvent.ADD_HOLE,currentNode.data.nextBorder,finalPosition));
					}
					currentNode = currentNode.next;
				}
				while(currentNode != _rooms[i].roomPointList.head)
			}
		}
		//判断自相交函数frank，false表示正常
		private function edgeIntersectAfterDragVertexInner(roomIndex:uint):Boolean
		{
			var roomData:RoomDataVO = _rooms[roomIndex];
			var H1:DListNode = roomData.roomPointList.head;
			while(1)
			{
				var H2:DListNode = H1.next
				while(1)
				{
					
					var EAPA:Point = new Point(H1.data.globalX,H1.data.globalY);
					var EAPB:Point = new Point(H1.next.data.globalX,H1.next.data.globalY);
					var EBPA:Point = new Point(H2.data.globalX,H2.data.globalY);
					var EBPB:Point = new Point(H2.next.data.globalX,H2.next.data.globalY);
					if(PolygonMath.edgeIntersect(EAPA,EAPB,EBPA,EBPB,true))
						return true;
					
					H2 = H2.next;
					if(H2 == roomData.roomPointList.head)
						break;
				}
				H1 = H1.next;
				if(H1 == roomData.roomPointList.head)
					break;
			}
			return false;
		}
		//判断外相交函数frank，false表示正常
		private function edgeIntersectAfterDragVertexOuter(roomIndex:uint):Boolean
		{
			var tempRoom:RoomDataVO = _rooms[roomIndex];
			//包围盒更新问题
			for(var i:int = 0; i < _rooms.length; i++)
			{
				if (_rooms[i] != tempRoom &&
					_rooms[i].roomMax.x > tempRoom.roomMin.x &&
					_rooms[i].roomMin.x < tempRoom.roomMax.x &&
					_rooms[i].roomMax.y > tempRoom.roomMin.y &&
					_rooms[i].roomMin.y < tempRoom.roomMax.y)
				{
					var H1:DListNode = _rooms[i].roomPointList.head;
					while(1)
					{
						var H2:DListNode = tempRoom.roomPointList.head;
						while(1)
						{
							var EAPA:Point = new Point(H1.data.globalX,H1.data.globalY);
							var EAPB:Point = new Point(H1.next.data.globalX,H1.next.data.globalY);
							var EBPA:Point = new Point(H2.data.globalX,H2.data.globalY);
							var EBPB:Point = new Point(H2.next.data.globalX,H2.next.data.globalY);
							
							if(PolygonMath.edgeIntersect(EAPA,EAPB,EBPA,EBPB))
								return true;
							
							H2 = H2.next;
							if(H2 == tempRoom.roomPointList.head)
								break;
						}
						H1 = H1.next;
						if(H1 == _rooms[i].roomPointList.head)
							break;
					}
				}
			}
			return false;
		}
		
		//判断顺时针，false表示正常
		private function clockwise(roomIndex:uint):Boolean
		{
			var H:DListNode = _rooms[roomIndex].roomPointList.head;
			var sum:Number = 0;
			var count:int = 0;
			while(1)
			{
				var v1:Point = new Point(H.data.globalX - H.prev.data.globalX, 	H.data.globalY - H.prev.data.globalY);
				var v2:Point = new Point(H.next.data.globalX - H.data.globalX, H.next.data.globalY - H.data.globalY);
				if(v1.x*v2.y - v2.x*v1.y > 0)
					sum = sum + Math.PI + PolygonMath.vectorAngle(v1,v2);
				else
					sum = sum + Math.PI - PolygonMath.vectorAngle(v1,v2);
				H = H.next;
				count++;
				if(H == _rooms[roomIndex].roomPointList.head)
					break;
			}
			if(Math.abs(sum/Math.PI - count + 2) < 0.1)
				return false;
			else
				return true;
		}
		public function roomRotate(roomIndex:uint, clockwise:Boolean):void
		{
			var angle:Number = -3*Math.PI/180;
			if(!clockwise)
				angle = +3*Math.PI/180;
			var VO:RoomDataVO = _rooms[roomIndex];
			var moveM1:Matrix = new Matrix(1,0,0,1,-VO.x,-VO.y);
			var moveM2:Matrix = new Matrix(1,0,0,1, VO.x, VO.y);
			var rotateM:Matrix = new Matrix(Math.cos(angle),Math.sin(angle),-Math.sin(angle),Math.cos(angle));
			moveM1.concat(rotateM);
			moveM1.concat(moveM2);
			var tranCenter:Point = moveM1.transformPoint(VO.roomCenter);
			var finalPosition:Point = new Point(currentRoom.x + VO.roomCenter.x - tranCenter.x,currentRoom.y + VO.roomCenter.y - tranCenter.y);
			VO.x += VO.roomCenter.x - tranCenter.x;
			VO.y += VO.roomCenter.y - tranCenter.y;
			VO.rotation = -angle*180/Math.PI+VO.rotation;//只要是修改了rotation房间就会将roomcenter修改
			dispatch(new SetRoomPositionEvent(SetRoomPositionEvent.SET_CURRENT_ROOM_POSITION,finalPosition));
			dispatch(new SetRoomRotationEvent(SetRoomRotationEvent.SET_CURRENT_ROOM_ROTATION,VO.rotation));			
		}
		public function get rooms():Vector.<RoomDataVO>
		{
			return _rooms;
		}
	}
	
}